package com.txts.road.admin.beidou.api.v1.util;

import java.util.ArrayList;
import java.util.List;

public class BeidouMessageParser {
    public static class PositionData {
        public String longitudeDirection;
        public int longitudeDegree;
        public int longitudeMinute;
        public int longitudeSecond;
        public int longitudeMillisecond;

        public String latitudeDirection;
        public int latitudeDegree;
        public int latitudeMinute;
        public int latitudeSecond;
        public int latitudeMillisecond;

        public double speed; // m/s
        public int direction; // degrees
        public String status;

        @Override
        public String toString() {
            return String.format("%s%02d°%02d′%02d″%02d, %s%02d°%02d′%02d″%02d, %.1f m/s, %d°, %s",
                    longitudeDirection, longitudeDegree, longitudeMinute, longitudeSecond, longitudeMillisecond,
                    latitudeDirection, latitudeDegree, latitudeMinute, latitudeSecond, latitudeMillisecond,
                    speed, direction, status);
        }
    }

    public static class ParsedMessage {
        public String header;
        public String type;
        public String reportTime;
        public int samplingFrequency;
        public int infoCount;
        public List<PositionData> positions = new ArrayList<>();
        public String checksum;

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            sb.append("Header: ").append(header).append("\n");
            sb.append("Type: ").append(type).append("\n");
            sb.append("Time: ").append(reportTime).append("\n");
            sb.append("Freq: ").append(samplingFrequency).append("s\n");
            sb.append("Count: ").append(infoCount).append("\n");
            for (int i = 0; i < positions.size(); i++) {
                sb.append("P").append(i + 1).append(": ").append(positions.get(i)).append("\n");
            }
            sb.append("Checksum: ").append(checksum);
            return sb.toString();
        }
    }

    public static ParsedMessage parseContent(String hex) throws Exception {
        if (hex == null || hex.length() < 30) throw new IllegalArgumentException("Content too short");
        ParsedMessage m = new ParsedMessage();
        int idx = 0;
        m.header = hex.substring(idx, idx += 2);
        m.type = hex.substring(idx, idx += 2);
        String t = hex.substring(idx, idx += 12);
        m.reportTime = parseTime(t);
        m.samplingFrequency = Integer.parseInt(hex.substring(idx, idx += 4), 16);
        m.infoCount = Integer.parseInt(hex.substring(idx, idx += 2), 16);
        for (int i = 0; i < m.infoCount; i++) {
            PositionData p = new PositionData();
            String lonDir = hex.substring(idx, idx += 2);
            p.longitudeDirection = parseDir(lonDir, true);
            p.longitudeDegree = Integer.parseInt(hex.substring(idx, idx += 2), 16);
            p.longitudeMinute = Integer.parseInt(hex.substring(idx, idx += 2), 16);
            p.longitudeSecond = Integer.parseInt(hex.substring(idx, idx += 2), 16);
            p.longitudeMillisecond = Integer.parseInt(hex.substring(idx, idx += 2), 16);
            String latDir = hex.substring(idx, idx += 2);
            p.latitudeDirection = parseDir(latDir, false);
            p.latitudeDegree = Integer.parseInt(hex.substring(idx, idx += 2), 16);
            p.latitudeMinute = Integer.parseInt(hex.substring(idx, idx += 2), 16);
            p.latitudeSecond = Integer.parseInt(hex.substring(idx, idx += 2), 16);
            p.latitudeMillisecond = Integer.parseInt(hex.substring(idx, idx += 2), 16);
            p.speed = Integer.parseInt(hex.substring(idx, idx += 4), 16) * 0.1;
            p.direction = Integer.parseInt(hex.substring(idx, idx += 4), 16);
            String st = hex.substring(idx, idx += 2);
            p.status = st.equalsIgnoreCase("00") ? "未定位" : "已定位";
            m.positions.add(p);
        }
        m.checksum = (idx + 2 <= hex.length() ? hex.substring(idx, idx + 2) : "");
        return m;
    }

    private static String parseTime(String h) {
        int y = Integer.parseInt(h.substring(0, 2), 16) + 2000;
        int mo = Integer.parseInt(h.substring(2, 4), 16);
        int d = Integer.parseInt(h.substring(4, 6), 16);
        int H = Integer.parseInt(h.substring(6, 8), 16);
        int mi = Integer.parseInt(h.substring(8, 10), 16);
        int s = Integer.parseInt(h.substring(10, 12), 16);
        return String.format("%04d-%02d-%02d %02d:%02d:%02d", y, mo, d, H, mi, s);
    }

    private static String parseDir(String d, boolean lon) {
        if (lon) return d.equalsIgnoreCase("45") ? "E" : d.equalsIgnoreCase("57") ? "W" : "?";
        return d.equalsIgnoreCase("4E") ? "N" : d.equalsIgnoreCase("53") ? "S" : "?";
    }
}
